package com.qs.cwams.util;

import com.qs.cwams.pojo.domain.AtteRuleDO;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;

/**
 * @author suncheng
 */
public class AtteDailyTime {
    private static AtteStandard standard;

    private final AtteRule rule;
    /**
     * 日期
     */
    private final LocalDate date;
    /**
     * 工作时间段
     */
    private List<TimeSlot> workTime = new ArrayList<>();

    private void init() {
        // 正常工作日
        if (date.getDayOfWeek() != DayOfWeek.SATURDAY && date.getDayOfWeek() != DayOfWeek.SUNDAY) {
            LocalDateTime amStartWork = LocalDateTime.of(date, standard.getAmStartTime());
            LocalDateTime amEndWork = LocalDateTime.of(date, standard.getAmEndTime());
            TimeSlot amWork = new TimeSlot(amStartWork, amEndWork);
            workTime.add(amWork);

            LocalDateTime pmStartWork = LocalDateTime.of(date, standard.getPmStartTime());
            LocalDateTime pmEndWork = LocalDateTime.of(date, standard.getPmEndTime());
            TimeSlot pmWork = new TimeSlot(pmStartWork, pmEndWork);
            workTime.add(pmWork);
        }
        // 特殊日期
        AtteRuleDO ruleDO = rule.get(date);
        if (ruleDO != null) {
            if (ruleDO.getType() == 0) {
                LocalDateTime startOver = LocalDateTime.ofInstant(ruleDO.getStartTime().toInstant(), ZoneId.systemDefault());
                LocalDateTime endOver = LocalDateTime.ofInstant(ruleDO.getEndTime().toInstant(), ZoneId.systemDefault());
                TimeSlot over = new TimeSlot(startOver, endOver);
                if (workTime.size() > 0) {
                    List<TimeSlot> newWorkTime = new ArrayList<>();
                    for (TimeSlot slot : workTime) {
                        TimeSlot newSlot = slot.merge(over);
                        if (newSlot != null) {
                            newWorkTime.add(newSlot);
                        } else {
                            newWorkTime.add(slot);
                        }
                    }
                    workTime = newWorkTime;
                } else {
                    // 周末加班排除午休时间
                    TimeSlot rest = standard.getRestSlot(date);
                    if (over.overlapsWith(rest)) {
                        List<TimeSlot> newWorkTime = over.exclude(rest);
                        if (newWorkTime.size() > 0) {
                            workTime.addAll(newWorkTime);
                        } else {
                            workTime.add(over);
                        }
                    } else {
                        workTime.add(over);
                    }
                }
            } else if (ruleDO.getType() == 1) {
                LocalDateTime startFree = LocalDateTime.ofInstant(ruleDO.getStartTime().toInstant(), ZoneId.systemDefault());
                LocalDateTime endFee = LocalDateTime.ofInstant(ruleDO.getEndTime().toInstant(), ZoneId.systemDefault());
                TimeSlot free = new TimeSlot(startFree, endFee);
                if (workTime.size() > 0) {
                    List<TimeSlot> newWorkTime = new ArrayList<>();
                    for (TimeSlot slot : workTime) {
                        if (slot.overlapsWith(free)) {
                            List<TimeSlot> newSlot = slot.exclude(free);
                            if (newSlot.size() > 0) {
                                newWorkTime.addAll(newSlot);
                            }
                        } else {
                            newWorkTime.add(slot);
                        }
                    }
                    workTime = newWorkTime;
                }
            }
        }
    }

    public AtteDailyTime(LocalDate date) {
        this.date = date;
        standard = new AtteStandard();
        rule = new AtteRule(date);
        init();
    }

    public LocalDate getDate() {
        return date;
    }

    public List<TimeSlot> getWorkTime() {
        return workTime;
    }
}
